package com.eco.controller;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eco.annotation.AuthToken;
import com.eco.constants.Constants;
import com.eco.entity.AiFishEntity;
import com.eco.entity.AiFishTypeEntity;
import com.eco.service.AiFishService;
import com.eco.utils.DateAndStringUtils;
import com.eco.utils.FilePathUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@RestController
@Api(tags = "鱼类识别计数查询")
public class AiFishController {

    @Resource
    private AiFishService aiFishServiceIn;

    private final StringRedisTemplate stringRedisTemplate;


    @Value("${station.filepath-in:}")
    private String preFilePathIn;

    @Value("${station.patternpath-in:}")
    private String prePatternPathIn;

    @Value("${station.routepath-in:}")
    private String preRoutePathIn;

    @Value("${station.filepath-out:}")
    private String preFilePathOut;

    @Value("${station.patternpath-out:}")
    private String prePatternPathOut;

    @Value("${station.routepath-out:}")
    private String preRoutePathOut;

    public AiFishController(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @GetMapping({"/getAiFishTable"})
    @AuthToken
    public JSONObject getAiFishTable(String startDate, String endDate, String pageNum, String point, String direction, String category, String length) {
        //查询视频图片地址先根据进口出口地址确定路径
        String preFilePath;
        String prePatternPath;
        String preRoutePath;
        if("out".equalsIgnoreCase(point)){
            preFilePath = preFilePathOut;
            prePatternPath = prePatternPathOut;
            preRoutePath = preRoutePathOut;
        }else{
            preFilePath = preFilePathIn;
            prePatternPath = prePatternPathIn;
            preRoutePath = preRoutePathIn;
        }
        //确定数据源
        String ds = getDS(point);
        DynamicDataSourceContextHolder.push(ds);
        try {
            JSONObject result = new JSONObject();
            if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate) || StringUtils.isEmpty(point)) {
                log.error("有日期参数或点位为空");
                result.put("msg", "日期参数或点位不能为空");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            if (StringUtils.isEmpty(pageNum)) {
                pageNum = "1";
            }

            Float lenMin = null;
            Float lenMax = null;
            if (!StringUtils.isEmpty(length) && StringUtils.contains(length, "-")) {
                String[] split = StringUtils.split(length.trim(), "-");
                if (StringUtils.endsWith(length, "-")) {
                    lenMin = Float.valueOf(split[0]);
                }
                if (split.length == 2) {
                    lenMin = Float.valueOf(split[0]);
                    lenMax = Float.valueOf(split[1]);
                }
            }
            List<AiFishEntity> aiFishList = null;
            JSONArray datas = new JSONArray();
            long total = 0;
            IPage<AiFishEntity> byDate = this.aiFishServiceIn.findByDate(startDate, endDate, Integer.parseInt(pageNum.trim()), 10, direction, category, lenMin, lenMax);
            aiFishList = byDate.getRecords();
            total = byDate.getTotal();
            if (CollectionUtils.isEmpty(aiFishList)) {
                log.error("未查询到过鱼数据");
                result.put("msg", "未查询到过鱼数据");
                result.put("status", Boolean.valueOf(true));
                result.put("data", null);
                return result;
            }
            aiFishList.stream().forEach(aiFishEntity -> {
                JSONObject data = new JSONObject();
                data.put("recordId", aiFishEntity.getId());
                data.put("recordTime", aiFishEntity.getCreatedAt());
                data.put("width", aiFishEntity.getWidth());
                data.put("length", aiFishEntity.getLength());
                data.put("weight", aiFishEntity.getWeight());
                data.put("direction", aiFishEntity.getSwim());
                //根据id和recordtime找到mp4和jpg文件
                //路径是statics/20240318/xxxxx/xxxx161833.mp4
                Date jdkDate = DateUtil.parse(aiFishEntity.getCreatedAt()).toJdkDate();
                String yyyyMMddPath = DateUtil.format(jdkDate, "yyyyMMdd");
                String prePath = preFilePath + "\\" + yyyyMMddPath;
                String patternPath = prePatternPath + "\\\\" + yyyyMMddPath + "\\\\[^\\\\]+\\\\fs_" + aiFishEntity.getId() + "_[^\\\\]+" + "\\.jpg";
                log.info("prePath={}", prePath);
                log.info("patternPath={}", patternPath);
                String filePath = FilePathUtil.getFilePath(prePath, patternPath);
                int i = filePath.lastIndexOf(".");
                if (-1 != i) {
                    filePath = filePath.substring(0, i);
                    filePath = filePath.replace(preFilePath, preRoutePath);
                }
                data.put("imgUrl", filePath + ".jpg");
                data.put("videoUrl", filePath + ".mp4");
                data.put("imgUrl2", data.get("imgUrl"));
                data.put("category", aiFishEntity.getFishType());
                datas.add(data);
            });
            log.info("查询过鱼识别数据（table）成功");
            result.put("status", Boolean.valueOf(true));
            result.put("data", datas);
            result.put("total", Long.valueOf(total));
            return result;
        } finally {
            DynamicDataSourceContextHolder.clear();
        }

    }

    @GetMapping({"/getAiOrSonarFishChart"})
    @AuthToken
    public JSONObject getSonarFishChart(String startDate, String endDate, String point, String mode) {
        String ds = getDS(point);
        DynamicDataSourceContextHolder.push(ds);
        try {
            JSONObject result = new JSONObject();
            if (StringUtils.isEmpty(startDate) || StringUtils.isEmpty(endDate)) {
                log.error("有日期参数或点位为空");
                result.put("msg", "日期参数或点位不能为空");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            JSONArray datas = new JSONArray();
            String dateStr = DateAndStringUtils.dateNow();
            List<AiFishEntity> aiFishEntityList = null;
            List<AiFishEntity> todayFishs = null;
            int up = 0;
            int down = 0;
            int upTotal = 0;
            int downTotal = 0;
            aiFishEntityList = this.aiFishServiceIn.findByRecordDateTime(startDate, endDate);
            todayFishs = this.aiFishServiceIn.findByRecordDateTime(dateStr + " 00:00:00", dateStr + " 23:59:59");
            AtomicInteger upNum = new AtomicInteger();
            AtomicInteger downNum = new AtomicInteger();
            if (CollectionUtils.isEmpty(todayFishs)) {
                upNum.set(0);
                downNum.set(0);
            } else {
                todayFishs.stream().forEach(aiFishEntity -> {
                    if ("0".equals(aiFishEntity.getSwim())) {
                        upNum.addAndGet(1);
                    } else {
                        downNum.addAndGet(1);
                    }
                });
            }
            up = upNum.intValue();
            down = downNum.intValue();
            upTotal = this.aiFishServiceIn.countAll("right");
            downTotal = this.aiFishServiceIn.countAll("left");
            if (CollectionUtils.isEmpty(aiFishEntityList)) {
                log.error("未查询到过鱼识别数据");
                result.put("msg",
                        "未查询到过鱼识别数据");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                result.put("todayUp", Integer.valueOf(up));
                result.put("todayDown", Integer.valueOf(down));
                result.put("todayTotal", Integer.valueOf(up + down));
                result.put("totalUp", Integer.valueOf(upTotal));
                result.put("totalDown", Integer.valueOf(downTotal));
                result.put("totalTotal", Integer.valueOf(upTotal + downTotal));
                return result;
            }
            aiFishEntityList.stream().forEach(aiFishEntity -> {
                JSONObject data = new JSONObject();
                data.put("recordTime", aiFishEntity.getCreatedAt());
                data.put("width", aiFishEntity.getWidth());
                data.put("length", aiFishEntity.getLength());
                data.put("weight", aiFishEntity.getWeight());
                data.put("direction", aiFishEntity.getSwim());
                data.put("category", stringRedisTemplate.opsForValue().get(Constants.FISH_TYPE_REDIS_KEY + aiFishEntity.getFishType()));
                datas.add(data);
            });
            log.info("查询过鱼识别数据(chart)成功");
            result.put("status", Boolean.valueOf(true));
            result.put("data", datas);
            result.put("todayUp", Integer.valueOf(up));
            result.put("todayDown", Integer.valueOf(down));
            result.put("todayTotal", Integer.valueOf(up + down));
            result.put("totalUp", Integer.valueOf(upTotal));
            result.put("totalDown", Integer.valueOf(downTotal));
            result.put("totalTotal", Integer.valueOf(upTotal + downTotal));
            return result;
        } finally {
            DynamicDataSourceContextHolder.clear();
        }

    }

    @PostMapping(value = {"/updateAiFish"}, consumes = {"application/json"})
    @AuthToken("admin")
    public JSONObject updateFishData(@RequestBody JSONObject data) {
        String ds = getDS(data.getString("point"));
        DynamicDataSourceContextHolder.push(ds);
        try {
            JSONObject result = new JSONObject();
            String id = data.getString("id");
            String fishType = data.getString("fishType");
            if (StringUtils.isEmpty(fishType) || StringUtils.isEmpty(id)) {
                log.error("fishType、id为空");
                result.put("msg", "fishType、id为空");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            AiFishEntity aiFishEntity = data.toJavaObject(AiFishEntity.class);
            if (aiFishEntity == null) {
                log.error("JSONObject转AiFishEntity异常");
                result.put("msg", "数据转换异常");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            aiFishEntity.setUpdatedAt(DateAndStringUtils.dateTimeNow());
            int isok = this.aiFishServiceIn.updateByAiFishEntity(aiFishEntity);
            if (isok < 1) {
                log.error("修改进口识别数据[{}]失败", id);
                result.put("msg", "操作数据库异常");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            log.info("修改进口识别数据[{}]成功", id);
            result.put("msg", "修改成功");
            result.put("status", Boolean.valueOf(true));
            result.put("data", null);
            return result;
        } finally {
            DynamicDataSourceContextHolder.clear();
        }

    }

    @RequestMapping({"/deleteAiFish"})
    @AuthToken("admin")
    public JSONObject deleteAiFish(int[] ids, String point) {
        String ds = getDS(point);
        DynamicDataSourceContextHolder.push(ds);
        try {
            JSONObject result = new JSONObject();
            if (ids.length == 0) {
                log.error("id数组为空");
                result.put("msg", "id数组为空");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            this.aiFishServiceIn.deleteById(ids);
            log.info("删除进口过鱼数据{}成功", ids);
            result.put("msg", "删除成功");
            result.put("status", Boolean.valueOf(true));
            result.put("data", null);
            return result;
        } finally {
            DynamicDataSourceContextHolder.clear();
        }

    }

    @GetMapping({"/getAllFishName"})
    @AuthToken
    public JSONObject getAllFishName(String point) {
        String ds = getDS(point);
        DynamicDataSourceContextHolder.push(ds);
        try {
            JSONObject result = new JSONObject();
            List<AiFishTypeEntity> allFishType = this.aiFishServiceIn.findAllFishType();
            if (CollectionUtils.isEmpty(allFishType)) {
                log.error("观察窗没有种类数据");
                result.put("status", Boolean.valueOf(false));
                result.put("data", null);
                return result;
            }
            JSONArray datas = new JSONArray();
            allFishType.stream().forEach(aiFishTypeEntity -> {
                JSONObject data = new JSONObject();
                data.put("fishName", aiFishTypeEntity.getFishName());
                data.put("fishType", aiFishTypeEntity.getObject());
                datas.add(data);
            });
            log.info("查询观察窗种类成功");
            result.put("status", Boolean.valueOf(true));
            result.put("data", datas);
            return result;
        } finally {
            DynamicDataSourceContextHolder.clear();
        }

    }

    /**
     * 动态选择数据源
     * @param point
     * @return
     */
    private String getDS(String point){
        if("out".equalsIgnoreCase(point)){
            return "ds2";
        }
        return "ds1";
    }


}
